package com.jhgsys.internal.hazard.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhgsys.internal.base.entity.HazardExamineUser;
import com.jhgsys.internal.base.service.IHazardExamineUserService;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.hazard.dto.HazardExamineDto;
import com.jhgsys.internal.hazard.dto.HazardExamineObjectDto;
import com.jhgsys.internal.hazard.dto.HazardExamineRecordDto;
import com.jhgsys.internal.hazard.dto.HazardExamineTeamDto;
import com.jhgsys.internal.hazard.entity.HazardExamine;
import com.jhgsys.internal.hazard.entity.HazardExamineObject;
import com.jhgsys.internal.hazard.entity.HazardExamineTeamUser;
import com.jhgsys.internal.hazard.mapper.HazardExamineMapper;
import com.jhgsys.internal.hazard.service.IHazardExamineObjectService;
import com.jhgsys.internal.hazard.service.IHazardExamineRecordService;
import com.jhgsys.internal.hazard.service.IHazardExamineService;
import com.jhgsys.internal.system.entity.Tenant;
import com.jhgsys.internal.system.service.ITenantService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 *  Service实现
 *
 * @author admin
 * @date 2024-08-19 14:13:44
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class HazardExamineServiceImpl extends ServiceImpl<HazardExamineMapper, HazardExamine> implements IHazardExamineService {

    @Autowired
    private ITenantService tenantService;

    @Autowired
    private IHazardExamineRecordService hazardExamineRecordService;

    @Autowired
    private IHazardExamineObjectService hazardExamineObjectService;

    @Autowired
    private IHazardExamineUserService hazardExamineUserService;

    /**
     * 查询（分页）
     * @author admin
     * @date 2024-08-19 14:13:44
     * @param request QueryRequest
     * @param hazardExamineDto hazardExamineDto
     * @return IPage<HazardExamine>
    */
    @Override
    public IPage<HazardExamineDto> findHazardExaminePage(QueryRequest request, HazardExamineDto hazardExamineDto) {
        IPage<HazardExamineDto> result = new  Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<HazardExamine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HazardExamine::getDeletedFlg, FebsConstant.VALID);
        //公司id
        if(StringUtils.isNotBlank(hazardExamineDto.getTenantId())){
            queryWrapper.eq(HazardExamine::getTenantId, hazardExamineDto.getTenantId());
        }
        //检查编号
        if(StringUtils.isNotBlank(hazardExamineDto.getExamineNo())){
            queryWrapper.like(HazardExamine::getExamineNo, hazardExamineDto.getExamineNo());
        }
        //检查标题
        if(StringUtils.isNotBlank(hazardExamineDto.getExamineTitle())){
            queryWrapper.like(HazardExamine::getExamineTitle, hazardExamineDto.getExamineTitle());
        }
        //检查类型
        if(StringUtils.isNotBlank(hazardExamineDto.getExamineType())){
            queryWrapper.eq(HazardExamine::getExamineType, hazardExamineDto.getExamineType());
        }
        //检查状态
        if(StringUtils.isNotBlank(hazardExamineDto.getStatus())){
            queryWrapper.eq(HazardExamine::getStatus, hazardExamineDto.getStatus());
        }
        queryWrapper.orderByDesc(HazardExamine::getCreatedTime);
        Page<HazardExamine> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        IPage<HazardExamine> pages = this.page(page, queryWrapper);
        List<HazardExamine> reportList = pages.getRecords();
        List<HazardExamineDto> dtoList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(reportList)){
            dtoList = BeanHelper.copyWithCollection(reportList,HazardExamineDto.class);
        }
        dtoList.forEach(p -> {
            Tenant tenant = tenantService.findTenantByTenantId(p.getTenantId());
            p.setTenantName(Optional.ofNullable(tenant).map(Tenant::getTenantName).orElse(""));
        });
        result.setRecords(dtoList);
        result.setTotal(dtoList.size());
        return result;
    }

    /**
     * 查询（分页）包含安全记录录入信息
     * @author admin
     * @date 2024-08-19 14:13:44
     * @param request QueryRequest
     * @param hazardExamineDto hazardExamineDto
     * @return IPage<HazardExamine>
    */
    @Override
    public IPage<HazardExamineDto> findHazardExaminePageWithRecords(QueryRequest request, HazardExamineDto hazardExamineDto) {
        IPage<HazardExamineDto> result = new  Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<HazardExamine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HazardExamine::getDeletedFlg, FebsConstant.VALID);
        //设置查询条件
        if(StringUtils.isNotBlank(hazardExamineDto.getTenantId())){
            queryWrapper.eq(HazardExamine::getTenantId, hazardExamineDto.getTenantId());
        }
        //检查标题
        if(StringUtils.isNotBlank(hazardExamineDto.getExamineTitle())){
            queryWrapper.like(HazardExamine::getExamineTitle, hazardExamineDto.getExamineTitle());
        }
        //检查类型
        if(StringUtils.isNotBlank(hazardExamineDto.getExamineType())){
            queryWrapper.eq(HazardExamine::getExamineType, hazardExamineDto.getExamineType());
        }
        queryWrapper.orderByDesc(HazardExamine::getCreatedTime);
        Page<HazardExamine> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        IPage<HazardExamine> pages = this.page(page, queryWrapper);
        List<HazardExamine> reportList = pages.getRecords();
        List<HazardExamineDto> dtoList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(reportList)){
            dtoList = BeanHelper.copyWithCollection(reportList,HazardExamineDto.class);
        }
        if(CollectionUtils.isNotEmpty(dtoList)){
            List<String> examineIds = dtoList.stream().map(p -> p.getExamineId()).collect(Collectors.toList());
            List<HazardExamineRecordDto> hazardExamineRecords = hazardExamineRecordService.findByExamineIds(examineIds);

            dtoList.forEach(p -> {
                List<HazardExamineRecordDto> recordDtoList =hazardExamineRecords.stream().filter(b ->b.getExamineId().equals(p.getExamineId())).collect(Collectors.toList());
                p.setHazardExamineRecords(recordDtoList);
                Tenant tenant = tenantService.findTenantByTenantId(p.getTenantId());
                p.setTenantName(Optional.ofNullable(tenant).map(Tenant::getTenantName).orElse(""));
            });

        }

        result.setRecords(dtoList);
        result.setTotal(dtoList.size());
        return result;
    }

    /**
     * 查询（所有）
     * @author admin
     * @date 2024-08-19 14:13:44
     * @param hazardExamine hazardExamine
     * @return List<HazardExamine>
     */
    @Override
    public List<HazardExamine> findHazardExamineList(HazardExamine hazardExamine) {
	    LambdaQueryWrapper<HazardExamine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HazardExamine::getDeletedFlg, 0);
		// TODO 设置查询条件
		return this.baseMapper.selectList(queryWrapper);
    }

    /**
    * 根据ID查询
    * @author admin
    * @date 2024-08-19 14:13:44
    * @param id
    * @return HazardExamineDto
    */
    @Override
    public HazardExamineDto findHazardExamineById(String id){
        HazardExamine hazardExamine = this.baseMapper.selectById(id);
        HazardExamineDto hazardExamineDto = BeanHelper.copyProperties(hazardExamine,HazardExamineDto.class);
        if(null != hazardExamineDto){
            Tenant tenant = tenantService.findTenantByTenantId(hazardExamineDto.getTenantId());
            if(ObjectUtils.isNotEmpty(tenant)){
                hazardExamineDto.setTenantName(tenant.getTenantName());
            }
            //查询检查项
            HazardExamineObject hazardExamineObject = new HazardExamineObject();
            hazardExamineObject.setExamineId(hazardExamine.getExamineId());
            List<HazardExamineObject> hazardExamineObjectList = hazardExamineObjectService.findHazardExamineObjectList(hazardExamineObject);
            if(CollectionUtils.isNotEmpty(hazardExamineObjectList)){
                List<HazardExamineObjectDto> hazardExamineObjectDtos = BeanHelper.copyWithCollection(hazardExamineObjectList, HazardExamineObjectDto.class);
                hazardExamineObjectDtos.forEach(d ->{
                    //查询检查项中的组信息
                    HazardExamineUser hazardExamineUser = new HazardExamineUser();
                    hazardExamineUser.setExamineObjectId(d.getExamineObjectId());
                    //查询hazard_examine_object关联的HazardExamineUser信息
                    List<HazardExamineUser> hazardExamineUserList = hazardExamineUserService.findHazardExamineUserList(hazardExamineUser);
                    //根据groupName对HazardExamineUser进行分组
                    Map<String,List<HazardExamineUser>> map = hazardExamineUserList.stream().collect(Collectors.groupingBy(HazardExamineUser::getGroupName));
//                    d.setGroupUserMap(map);
                    List<HazardExamineTeamDto> teamList = new ArrayList<>();
                    //将根据组名分组后的数据组装成teamList传给前端
                    map.forEach((k,v) ->{
                        HazardExamineTeamDto hazardExamineTeamDto = new HazardExamineTeamDto();
                        hazardExamineTeamDto.setTeamName(k);
                        List<HazardExamineTeamUser> hazardExamineTeamUserList = v.stream().map(b ->{
                            HazardExamineTeamUser hazardExamineTeamUser = BeanHelper.copyProperties(b,HazardExamineTeamUser.class);
                            hazardExamineTeamUser.setUserDeptId(b.getDeptId());
                            hazardExamineTeamUser.setUserDeptName(b.getDeptName());
                            return hazardExamineTeamUser;
                        }).collect(Collectors.toList());
                        hazardExamineTeamDto.setTeamUserList(hazardExamineTeamUserList);
                        teamList.add(hazardExamineTeamDto);
                    });
                    d.setTeamList(teamList);
                });
                hazardExamineDto.setObjectList(hazardExamineObjectDtos);
            }
        }
        return hazardExamineDto;
    }

    /**
     * 新增
     * @author admin
     * @date 2024-08-19 14:13:44
     * @param hazardExamine hazardExamine
     */
    @Override
    @Transactional
    public void createHazardExamine(HazardExamine hazardExamine) {
        hazardExamine.setCreatedTime(new Date());
        this.save(hazardExamine);
    }

    /**
     * 修改
     * @author admin
     * @date 2024-08-19 14:13:44
     * @param hazardExamineDto hazardExamineDto
     */
    @Override
    @Transactional
    public void updateHazardExamine(HazardExamineDto hazardExamineDto) {
        HazardExamine hazardExamine = BeanHelper.copyProperties(hazardExamineDto,HazardExamine.class);
        hazardExamine.setUpdatedTime(new Date());
        this.saveOrUpdate(hazardExamine);
    }

    /**
     * 逻辑删除
     * @author admin
     * @date 2024-08-19 14:13:44
     * @param hazardExamine hazardExamine
     * @param hazardExamineIds hazardExamineIds
     */
    @Override
    @Transactional
    public void deleteHazardExamine(HazardExamine hazardExamine,String hazardExamineIds) {
        List<String> list = Arrays.asList(hazardExamineIds.split(StringPool.COMMA));
        this.baseMapper.update(hazardExamine,new LambdaQueryWrapper<HazardExamine>().in(HazardExamine::getExamineId,list));
	}

    /**
    * 物理删除
    * @author admin
    * @date 2024-08-19 14:13:44
    * @param hazardExamineIds hazardExamineIds
    */
    @Override
    @Transactional
    public void physicallyDeleteHazardExamine(String hazardExamineIds) {
        List<String> list = Arrays.asList(hazardExamineIds.split(StringPool.COMMA));
        LambdaQueryWrapper<HazardExamine> wapper = new LambdaQueryWrapper<>();
        wapper.in(HazardExamine::getExamineId,list);
        this.remove(wapper);
    }

    /**
     * 生成检查编号 年+公司编码+序列号（5位）
     * @author admin
     * @date 2024-08-07 16:43:01
     * @param tenantId 公司ID
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public String createExamineNo(String tenantId) throws FebsException{
        String examineNo = "";

        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Tenant tenant = tenantService.getById(tenantId);
        if(null == tenant || StringUtils.isBlank(tenant.getTenantCode())){
            throw new FebsException("安全检查编号生成异常");
        }
        String tenantCode = tenant.getTenantCode();
        LambdaQueryWrapper<HazardExamine> queryWrapper = new LambdaQueryWrapper<HazardExamine>();
        queryWrapper.eq(HazardExamine::getTenantId,tenantId);
        queryWrapper.apply("DATE_FORMAT(created_time,'%Y') = DATE_FORMAT(NOW(),'%Y')");
        List<HazardExamine> hazardExamineList = this.baseMapper.selectList(queryWrapper);
        Integer length = hazardExamineList.size();
        String yearStr = String.valueOf(calendar.get(Calendar.YEAR));
        String sequencePrefix = "";
        if (length < 99999) {
            sequencePrefix = String.format("%5d", length + 1).replace(" ", "0");
        } else {
            sequencePrefix = String.format("%8d", length + 1).replace(" ", "0");
        }
        examineNo = yearStr + tenantCode + sequencePrefix;
        return examineNo;
    }

    /**
     * 校验安全检查是否关闭
     * @author admin
     * @date 2024-09-12 16:43:01
     * @param examineId 主键ID
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Boolean ifClosed(String examineId){
        LambdaQueryWrapper<HazardExamine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(HazardExamine::getExamineId,examineId);
        wrapper.eq(HazardExamine::getStatus,"4");
        return this.baseMapper.exists(wrapper);
    }

}
